package com.itheima.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
 *
 * @Aspect: 标记了该类，该类为 切面类
 * @Component: 创建bean对象
 * 切面： 增强 + 切入点
 *
 * 增强对象
 */
@Aspect
@Component
public class AOPAdvice_ann {

    @Pointcut("execution(* com.itheima.service..*.*(..))")
    public void Pointcut(){}

    @Before("Pointcut()")
    public void before(JoinPoint joinPoint) {

        System.out.println("参数数组：" + joinPoint.getArgs());
        System.out.println("目标对象：" + joinPoint.getTarget());
        System.out.println("方法签名：" + joinPoint.getSignature());
        System.out.println("方法名：" + joinPoint.getSignature().getName());

        System.out.println("前值增强:我在方法前执行");
    }

    @After("Pointcut()")
    public void after() {

        System.out.println("最终增强:我在方法后执行-- 总会执行");
    }

    @AfterReturning("Pointcut()")
    public void afterReturning() {

        System.out.println("后置增强:我在方法后执行");
    }

    @AfterThrowing(value = "Pointcut()",throwing = "e")
    public void afterThrowing(Throwable e) {

        System.out.println("捕获异常:" + e.getMessage());
        System.out.println("异常增强:我在方法抛出异常后执行");
    }

    @Around("Pointcut()")
    //环绕增强
    public void around(ProceedingJoinPoint proceedingJoinPoint) {
        // joinPoint 连接点
        // 所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点,所有的方法都是连接点
        try {
            System.out.println("前置增强");

            //环绕增强 必须调用原始方法
            proceedingJoinPoint.proceed(proceedingJoinPoint.getArgs()); //可以不传参

            System.out.println("后置增强");

        } catch (Throwable throwable) {
            throwable.printStackTrace();
            System.out.println("异常增强");

        } finally {
            System.out.println("最终增强");
        }
    }
}